#ifndef STATIC_HPP_INCLUDED
#define STATIC_HPP_INCLUDED

#include <string>
#include <map>
#include <vector>
#include <stack>

#include "../ParserLexer/treestruct.hpp"


using namespace std;

/* ----------------- */
/* Type declarations */
/* ----------------- */

enum types {integer, boolean, record, array, function, procedure, misc, pending};


typedef struct mytree_typed
{
    enum treetype nodetype;
    char* contenttype;
    struct
    {
        struct mytree_typed *first, *second, *third;
        enum ast_ops operateur;
    } an_operateur;
    int a_number;
    int a_boolean;
    char* a_variable;
} tree_typed;


typedef struct access_type_struct
{
    int access_state;
    string type;
} access_type;



/* --------------------------- */
/* Static function definitions */
/* --------------------------- */

/*
static string types_printer(enum types to_print)
{
    switch (to_print)
    {
        case integer: return "integer";
        case boolean: return "boolean";
        case array: return "array";
        case record: return "record";
        case pending: return "pending";
        case misc: return "misc";
        case function: return "function";
        case procedure: return "procedure";
    }
}
*/

static enum types inverted_types_printer(char* c_type)
{
    string type_string = string(c_type);
    if (type_string == "integer")
    {
        return integer;
    }
    else if (type_string == "boolean")
    {
        return boolean;
    }
    else if (type_string == "array")
    {
        return array;
    }
    else if (type_string == "record")
    {
        return record;
    }
    else if (type_string == "misc")
    {
        return misc;
    }
    else
    {
        return pending;
    }
}



/* --------------------------- */
/* Global variable declaration */
/* --------------------------- */

static string curr_accessing;
static string curr_type;

static stack<string> curr_defining;
static stack<string> curr_arg_list;
static stack<string> new_arg_list;

static vector<map<string, access_type> > var_list;

static map<string, int> proc_list;
static map<string, enum types> type_list;
static map<string, string> record_list;
static map<string, string> array_list;
static map<string, string> func_type_list;
static map<string, string> array_prototype_list;

static map<string, map<string, access_type> > var_record_list;
static map<string, map<string, string> > record_prototype_list;
static map<string, stack<string> > procfunc_arg_list;



/* ------------------- */
/* Function prototypes */
/* ------------------- */

// tree_cpp* preprocess_tree(tree simple);
int check_variable(string unchecked_var, int argmt);
void assign_type(tree id_tree, char* type_name);
void type_add(tree id_tree, char* type_name, enum types type);
void assign_field_type(tree id_tree, char* type_name);
char* retrieve_var_type(char* var);
tree_typed* static_analysis(tree unchecked, int var_arg);
void static_analysis_init();


#endif // STATIC_HPP_INCLUDED
